﻿using KYJBLL;
using KYJScadaProModbusRtu;
using SeeSharpTools.JY.GUI;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Diagnostics;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using thinger.DataConvertLib;

namespace KYJScadaProModbusRTU
{
    public partial class FrmHistoryTrend : Form
    {
        public FrmHistoryTrend()
        {
            InitializeComponent();

            //通过代码设置chart属性
            //x轴的数据类型
            this.chart_HistorylTrend.XDataType = StripChartX.XAxisDataType.String;

            //设置图例
            this.chart_HistorylTrend.LegendVisible = false;

            //设置显示的数据点
            this.chart_HistorylTrend.DisplayPoints = 100000;

            //Y轴的范围
            this.chart_HistorylTrend.AxisY.Minimum = -10.0f;
            this.chart_HistorylTrend.AxisY.Maximum = 50.0;
            this.chart_HistorylTrend.AxisY.AutoScale = false;

            //Y2轴的范围
            this.chart_HistorylTrend.AxisY2.Minimum = 0.0f;
            this.chart_HistorylTrend.AxisY2.Maximum = 1.0;
            this.chart_HistorylTrend.AxisY2.AutoScale = false;

            //设置一下初始时间
            this.dtp_Start.Value = DateTime.Now.AddHours(-2.0);
            this.dtp_End.Value = DateTime.Now;

            if (CommomMethods.plcDevice != null && CommomMethods.sysConfig != null)
            {
                //初始化selectParam
                for (int i = 0; i < Math.Min(CommomMethods.sysConfig.ShowSeriesCount, CommomMethods.plcDevice.StoreVarList.Count); i++)
                {
                    selectParam.Add(CommomMethods.plcDevice.StoreVarList[i].Comments);
                }

                BindCombBox();
            }
        }

        private void BindCombBox()
        {
            this.cmb_Param.SelectedIndexChanged -= this.cmb_Param_SelectedIndexChanged;
            this.cmb_Param.DataSource = selectParam;
            this.cmb_Param.SelectedIndexChanged += this.cmb_Param_SelectedIndexChanged;
        }

        private void cmb_Param_SelectedIndexChanged(object sender, EventArgs e)
        {
            for (int i = 0; i < this.chart_HistorylTrend.SeriesCount; i++)
            {
                this.chart_HistorylTrend.Series[i].Visible = this.chart_HistorylTrend.Series[i].Name == this.cmb_Param.Text;
            }
        }

        //创建一个实时数据查询的业务对象
        private ActualDataManage actualDataManage = new ActualDataManage();

        /// <summary>
        /// 创建需要查询参数集合
        /// </summary>
        private List<string> selectParam = new List<string>();

        /// <summary>
        /// 查询数据
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btn_Query_Click(object sender, EventArgs e)
        {
            string start = this.dtp_Start.Text;
            string end = this.dtp_End.Text;

            Task<OperateResult<DataTable>> task = Task.Run(() =>
            {
                return QueryProcess(start, end);
            });
            var result = task.GetAwaiter().GetResult();

            if (result.IsSuccess)
            {
                //显示
                UpdateChart(result.Content, Convert.ToDateTime(start), Convert.ToDateTime(end));
            }
            else
            {
                new FrmMessageBoxWithoutAck("查询出错:" + result.Message,"查询出错").ShowDialog();
            }
        }

        /// <summary>
        /// 更新曲线控件
        /// </summary>
        /// <param name="content"></param>
        /// <param name="dateTime1"></param>
        /// <param name="dateTime2"></param>
        private void UpdateChart(DataTable dataTable, DateTime start, DateTime end)
        {
            //清除CharHistory
            this.chart_HistorylTrend.Clear();

            //获取曲线的数量
            int count = selectParam.Count;

            //重新设置Chart中曲线的数量
            this.chart_HistorylTrend.SeriesCount = count;

            for (int i = 0; i < count; i++)
            {
                this.chart_HistorylTrend.Series[i].Name = selectParam[i];
                this.chart_HistorylTrend.Series[i].Width = StripChartXSeries.LineWidth.Middle;
                this.chart_HistorylTrend.Series[i].Visible = true;

                //设置Y轴
                if (selectParam[i].Contains("温度"))
                {
                    this.chart_HistorylTrend.Series[i].YPlotAxis = StripChartXAxis.PlotAxis.Primary;
                }
                else
                {
                    this.chart_HistorylTrend.Series[i].YPlotAxis = StripChartXAxis.PlotAxis.Secondary;
                }
            }

            //数据绑定
            string[] XDate = GetTimeList(start, end).ToArray();

            double[,] YData = new double[count, XDate.Length];

            var valueList = GetDicValuesFromDataTable(dataTable);

            for (int i = 0; i < XDate.Length; i++)
            {
                //如果包含这个时间点，说明这个时间点就有数据
                if (valueList.ContainsKey(XDate[i]))
                {
                    for (int j = 0; j < count; j++)
                    {
                        try
                        {
                            YData[j, i] = Convert.ToDouble(valueList[XDate[i]][j]);
                        }
                        catch (Exception)
                        {

                            YData[j, i] = 0;
                        }
                    }
                }
                //如果不包含这个时间点，说明这个时间点就有数据
                else
                {
                    for (int j = 0; j < count; j++)
                    {
                        YData[j, i] = 0;
                    }
                }
            }

            this.chart_HistorylTrend.Plot(YData, XDate);
        }

        /// <summary>
        /// 根据起始时间和结束时间进行查询
        /// </summary>
        /// <param name="start"></param>
        /// <param name="end"></param>
        /// <returns></returns>
        private OperateResult<DataTable> QueryProcess(string start, string end)
        {
            if (selectParam.Count == 0)
            {
                return OperateResult.CreateFailResult<DataTable>("至少需要选择一个参数");
            }
            //判断时间
            DateTime startTime = Convert.ToDateTime(start);
            DateTime endTime = Convert.ToDateTime(end);

            if (startTime > endTime)
            {
                return OperateResult.CreateFailResult<DataTable>("开始时间不能大于结束时间");
            }

            TimeSpan timeSpan = endTime - startTime;

            if (timeSpan.TotalHours > 24.0)
            {
                return OperateResult.CreateFailResult<DataTable>("查询时间不能大于24小时");
            }

            //查询参数对应字段集合
            var columns = selectParam.Select(c => CommomMethods.plcDevice.StoreVarList.FirstOrDefault(d => d.Comments == c).VarName).ToList();

            DataTable dataTable = actualDataManage.QueryActualDataByTime(start, end, columns);

            if (dataTable != null && dataTable.Rows.Count > 0)
            {
                return OperateResult.CreateSuccessResult<DataTable>(dataTable);
            }
            else
            {
                return OperateResult.CreateFailResult<DataTable>("该段时间内无可用数据,请检查");
            }
        }

        /// <summary>
        /// 获取开始时间和结束时间之间的时间点集合
        /// </summary>
        /// <param name="start"></param>
        /// <param name="end"></param>
        /// <returns></returns>
        public List<string> GetTimeList(DateTime start, DateTime end)
        {
            List<string> timeList = new List<string>();
            DateTime t1 = start;
            while (t1 <= end)
            {
                timeList.Add(t1.ToString("yyyy-MM-dd HH:mm:ss"));
                t1 = t1.AddSeconds(1);
            }
            return timeList;
        }

        /// <summary>
        /// 将dataTable拆分成字典集合，键是时间，值是参数数据集合
        /// </summary>
        /// <param name="dataTable"></param>
        /// <returns></returns>
        private Dictionary<string, List<string>> GetDicValuesFromDataTable(DataTable dataTable)
        {

            Dictionary<string, List<string>> valueList = new Dictionary<string, List<string>>();
            for (int i = 0; i < dataTable.Rows.Count; i++)
            {
                string dateTime = dataTable.Rows[i][0].ToString();
                List<string> temp = new List<string>();
                for (int j = 0; j < dataTable.Columns.Count - 1; j++)
                {
                    temp.Add(dataTable.Rows[i][j + 1].ToString());
                }
                if (!valueList.ContainsKey(dateTime))
                {
                    valueList.Add(dateTime, temp);
                }
            }
            return valueList;
        }

        #region 保存
        private void btn_Save_Click(object sender, EventArgs e)
        {
            SaveFileDialog saveFileDialog = new SaveFileDialog();

            saveFileDialog.Filter = "图片文件(*.jpg)|*.jpg|所有文件|*.*";
            saveFileDialog.FileName = "趋势保存图片" + DateTime.Now.ToString("yyyyMMddHHmmss");

            saveFileDialog.Title = "历史趋势保存文件";
            saveFileDialog.DefaultExt = "jpg";
            saveFileDialog.AddExtension = true;

            if(saveFileDialog.ShowDialog() == DialogResult.OK)
            {
                this.chart_HistorylTrend.SaveAsImage(saveFileDialog.FileName);
                Process.Start(saveFileDialog.FileName);
            }
        }
        #endregion

        #region 导出
        private void btn_Export_Click(object sender, EventArgs e)
        {
            SaveFileDialog saveFileDialog = new SaveFileDialog();

            saveFileDialog.Filter = "CSV文件(*.csv)|*.csv|所有文件|*.*";
            saveFileDialog.FileName = "趋势保存图片" + DateTime.Now.ToString("yyyyMMddHHmmss");

            saveFileDialog.Title = "历史趋势保存文件";
            saveFileDialog.DefaultExt = "csv";
            saveFileDialog.AddExtension = true;

            if (saveFileDialog.ShowDialog() == DialogResult.OK)
            {
                this.chart_HistorylTrend.SaveAsCsv(saveFileDialog.FileName);
                Process.Start(saveFileDialog.FileName);
            }
        }
        #endregion

        private void btn_SelectParam_Click(object sender, EventArgs e)
        {
            FrmParamSel frmParamSel = new FrmParamSel(this.selectParam);

            if(frmParamSel.ShowDialog() == DialogResult.OK)
            {
                this.selectParam = frmParamSel.SelectParamList;

                BindCombBox();
            }
        }

        #region 减少闪烁
        protected override CreateParams CreateParams
        {
            get
            {
                CreateParams parss = base.CreateParams;
                parss.ExStyle |= 0x02000000;
                return parss;
            }
        }
        #endregion
    }
}
